<template>
  <div>
    <!-- 遮罩层，点击遮罩层隐藏计算器 -->
    <!-- <div class="mask" @click="$emit('hideCalc')"></div> -->
    <div :style="{ top: top + 'px', left: left + 'px' }" class="calculator">
      <div class="showPanel">
        <span class="exp">{{ exp }}</span>
        <span class="number">{{ number }}</span>
      </div>
      <div class="caculator-button">
        <el-button @click="getResult('c')">c</el-button>
        <el-button @click="getResult('/')">/</el-button>
        <el-button @click="getResult('*')">*</el-button>
        <el-button @click="getResult('del')" icon="delete"> </el-button>

        <el-button @click="getResult('7')">7</el-button>
        <el-button @click="getResult('8')">8</el-button>
        <el-button @click="getResult('9')">9</el-button>
        <el-button @click="getResult('-')">-</el-button>

        <el-button @click="getResult('4')">4</el-button>
        <el-button @click="getResult('5')">5</el-button>
        <el-button @click="getResult('6')">6</el-button>
        <el-button @click="getResult('+')">+</el-button>

        <el-button @click="getResult('1')">1</el-button>
        <el-button @click="getResult('2')">2</el-button>
        <el-button @click="getResult('3')">3</el-button>
        <el-button @click="getResult('=')" type="primary" class="equal">=</el-button>

        <el-button @click="getResult('+/-')">+/-</el-button>
        <el-button @click="getResult('0')">0</el-button>
        <el-button @click="getResult('.')">.</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import {parseExpression} from '@/utils/changeData.js'
export default {
  name: 'calculator',
  props: {
    calcTop: {
      // calcTop，calcLeft计算器的位置
      type: Number,
      default: 100
    },
    calcLeft: {
      type: Number,
      default: 100
    }
  },
  data() {
    return {
      number: '0', // 当前显示在输入框的数值，这里要注意number时刻是个字符串格式，否则indexOf方法会报错
      exp: '', // 用于计算和显示的表达式
      rewrite: false, // 是否要清空输入框重写，比如按下5后，再按+，下次再按一个数字是，就需要清空输入框重写
      isInit: false // 是否需要初始化，比如按下=号后，继续按键
    }
  },
  computed: {
    top() {
      // 计算器定位，距离边距的处理
      if (this.calcTop < 270) {
        return 300
      } else {
        return 400
      }
    },
    left() {
      // 计算器定位
      return this.calcLeft < 0 ? 30 : this.calcLeft
    },
    // 键盘按键与事件之间的对应关系
    keyMap() {
      return new Map([
        ['0', this.getResult.bind(this, '0')],
        ['1', this.getResult.bind(this, '1')],
        ['2', this.getResult.bind(this, '2')],
        ['3', this.getResult.bind(this, '3')],
        ['4', this.getResult.bind(this, '4')],
        ['5', this.getResult.bind(this, '5')],
        ['6', this.getResult.bind(this, '6')],
        ['7', this.getResult.bind(this, '7')],
        ['8', this.getResult.bind(this, '8')],
        ['9', this.getResult.bind(this, '9')],
        ['Backspace', this.getResult.bind(this, 'del')],
        ['/', this.getResult.bind(this, '/')],
        ['*', this.getResult.bind(this, '*')],
        ['+', this.getResult.bind(this, '+')],
        ['-', this.getResult.bind(this, '-')],
        ['.', this.getResult.bind(this, '.')],
        ['c', this.getResult.bind(this, 'c')],
        ['Enter', this.getResult.bind(this, '=')]
      ])
    }
  },
  onLoad() {
    uni.onKeyboardHeightChange(this.keyEvent);
  },
  onUnload() {
    uni.offKeyboardHeightChange(this.keyEvent);
  },

  methods: {
    // 按下按键
    getResult(e) {
      // 如果之前按下了等号，重置数据
      if (this.isInit) {
        this.isInit = false
        Object.assign(this.$data, this.$options.data())
      }
      // 不可以连续点击多个小数点
      if (this.number.indexOf('.') != -1 && e === '.') return
      if (/[0-9]|./.test(e)) {
        // 如果是小数点或者数字，就给this.number赋值
        if (this.rewrite) {
          this.number = e
          this.rewrite = false
        } else {
          if (this.number === '0' && e !== '.') {
            this.number = e // 避免输入多个0的情况，00005
          } else {
            // 可以输入：0.5
            this.number += e
          }
        }
      } else if (['+', '-', '*', '/'].includes(e)) {
        // 上一次按下的也是运算符号，则需要覆盖最后一个运算符号
        let last = this.exp.charAt(this.exp.length - 1)
        if (this.rewrite && ['+', '-', '*', '/'].includes(last)) {
          this.exp = this.exp.slice(0, this.exp.length - 1) + e
        } else {
          this.rewrite = true  // 下次输入数字时需要重置this.number
          this.exp += this.number + e
        }
      } else if (e === 'del') {
        if (this.number === '0') return
        if (this.rewrite) return // 上一次点的是运算符号，不可以删除
        this.number = this.number.slice(0, this.number.length - 1)
        if (this.number === '') this.number = '0'
      } else if (e === '+/-') {
        // 取反
        this.number = (-1 * this.number).toString()
      } else if (e === '=') {
        this.exp += this.number
        // 算出结果
        this.number = parseExpression(this.exp).toString()
        this.exp += e
        this.isInit = true
        // 相父组件传出结果
        this.$emit('getCalcResult', this.number)
      } else if (e === 'c') {
        Object.assign(this.$data, this.$options.data())
      }
    },
    /**
     * @description  监听键盘事件
     */
    keyEvent(e) {
      this.keyMap.get(e.key) && this.keyMap.get(e.key)()
    }
  }
}
</script>

<style lang="scss" scoped>
.mask {
  position: absolute;
  z-index: 80;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
}
.calculator {
  position: fixed;
  z-index: 99;
  border: solid 1px #dcdfe6;
  padding: 5px;
  background-color: #fffffff1;
  border-radius: 4px;
  box-shadow: 0 0 2px #dcdfe6;

  .showPanel {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    padding: 2px 20px;
    height: 42px;
    border: 1px #f0f0f0 solid;
    width: 203px;
    border-radius: 4px;
    box-sizing: border-box;
    margin-bottom: 3px;
    justify-content: space-evenly;
    .exp {
      color: #aaa;
      font-size: 10px;
      height: 12px;
    }
    .number {
      font-size: 16px;
      font-weight: 900;
    }
  }
  // 删除的icon图标
  ::v-deep.delete {
    display: inline-block;
    width: 20px;
    height: 12px;
    background: url('../../icon/calcDetele.png') no-repeat center center;
    background-size: 90% 90%;
  }
}
.el-button {
  margin: 0 !important;
  padding: 10px;
  font-weight: 600;
  width: 100%;
}
.caculator-button {
  margin: 0 auto;
  width: 190px;
  display: grid;
  border: solid 1px #eee;
  padding: 6px;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 3px;
  border-radius: 4px;
  background-color: #fffffff1;
}
#result {
  margin-bottom: 6px;
}
.equal {
  grid-column: 4/5;
  grid-row: 4/6;
}
</style>
